package models;

import java.io.Serializable;
import javax.persistence.*;

import models.Doc.Category;
import models.Doc.Type;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * The persistent class for the doc database table.
 * 
 */
@Entity
@Table(name = "DOC")
public class Doc implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @TableGenerator(
            name = "DOC_SEQ",
            table = "SEQUENCE",
            pkColumnName = "NAME",
            pkColumnValue = "DOC_SEQ",
            valueColumnName = "CNT",
            initialValue = 10000,
            allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "DOC_SEQ")
    @Column(unique = true, nullable = false)
    private Integer id;

    private Integer aid;

    private int category;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CREATE_D")
    private Date createD;

    @Column(name = "LOAN_APP_ID")
    private Integer loanAppId;

    private int mandatory;

    private int status;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "STATUS_D")
    private Date statusD;

    private int type;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "UPDATE_D")
    private Date updateD;

    private Integer uploader;

    @Column(length = 50)
    private String version;

    public Doc() {
    }

    public void setValues(Status status, Mandatory mandatory) {
        this.setStatus(status);
        this.setMandatory(mandatory);
        this.setUpdateD(new Date());
    }

    public void setupEmplyDoc(Integer aid, Integer loanAppId, Status status, Mandatory mandatory, Category ctgry,
            Type type) {
        this.setAid(aid);
        this.setLoanAppId(loanAppId);
        this.setValues(status, mandatory);
        this.setCategory(ctgry);
        this.setType(type);
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getAid() {
        return this.aid;
    }

    public void setAid(Integer aid) {
        this.aid = aid;
    }

    public Category getCategory() {
        return Category.values()[this.category];
    }

    public void setCategory(Category category) {
        this.category = category.ordinal();
    }

    public Date getCreateD() {
        return this.createD;
    }

    public void setCreateD(Date createD) {
        this.createD = createD;
    }

    public Integer getLoanAppId() {
        return this.loanAppId;
    }

    public void setLoanAppId(Integer loanAppId) {
        this.loanAppId = loanAppId;
    }

    public Mandatory getMandatory() {
        return Mandatory.values()[this.mandatory];
    }

    public void setMandatory(Mandatory mandatory) {
        this.mandatory = mandatory.ordinal();
    }

    public Status getStatus() {
        return Status.values()[this.status];
    }

    public void setStatus(Status status) {
        this.status = status.ordinal();
    }

    public Date getStatusD() {
        return this.statusD;
    }

    public void setStatusD(Date statusD) {
        this.statusD = statusD;
    }

    public Type getType() {
        return Type.values()[this.type];
    }

    public void setType(Type type) {
        this.type = type.ordinal();
    }

    public Date getUpdateD() {
        return this.updateD;
    }

    public void setUpdateD(Date updateD) {
        this.updateD = updateD;
    }

    public Integer getUploader() {
        return this.uploader;
    }

    public void setUploader(Integer uploader) {
        this.uploader = uploader;
    }

    public String getVersion() {
        return this.version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public enum Mandatory {
        NO,
        YES
    }

    public static enum Type {
        BORROWERS_AGREEMENT("Borrower's agreement", Category.AGREEMENT, false), // 0
        CREDIT_PROFILE_AGREEMENT("Credit Profile's agreement", Category.AGREEMENT, false), // 1
        LENDERS_AGREEMENT("Lender's agreement", Category.AGREEMENT, false), // 2
        LENDERS_FIN_SUITABILITY_AGREEMENT("Lender's fin suitability agreement", Category.AGREEMENT, false), // 3
        LENDERS_TRUST_DECL_AGREEMENT("Lender's trust declaration agreement", Category.AGREEMENT, false), // 4
        TAX_WITHHOLDING_ACCEPT("Tax withholding accept", Category.STATEMENT, false), // 5
        TERMS_OF_AGREEMENT_ACCEPT("Terms of agreement accept", Category.STATEMENT, false), // 6
        MA_BORROWER_AGREEMENT("Massachusetts' borrower agreement ", Category.AGREEMENT, false), // 7
        TAX_1099INT("Tax 1099 int", Category.TAX, false), // 8 -
        TAX_1099OID("Tax 1099 oid", Category.TAX, false), // 9 -
        TAX_1099MISC("Tax 1099 misc", Category.TAX, false), // 10 -
        TAX_1099B("Tax 1099 B", Category.TAX, false), // 11 -
        TAX_1099C("Tax 1099 C", Category.TAX, false), // 12 -
        // SL Borrower Documents
        IDENTITY_CARD("ID Card", Category.BORROWER_DOCS, Group.GENERAL, false), // 15
        PBOC_CREDIT_REPORT("PBOC Credit Report", Category.BORROWER_DOCS, Group.GENERAL, false), // 16
        RESIDENCE_REGISTRATION("Residence Registration Card ", Category.BORROWER_DOCS, Group.GENERAL, false), // 18
        BANK_CARD("Bank Card", Category.BORROWER_DOCS, Group.GENERAL, false), // 14
        BANK_STATEMENT("Bank Statement", Category.BORROWER_DOCS, Group.GENERAL, false), // 14
        PROOF_OF_SALARY("Proof of Salary", Category.BORROWER_DOCS, Group.PERSONAL, false), // 19
        PROPERTY_TITLE_CERTIFICATE("Property Title Certificate", Category.BORROWER_DOCS, Group.GENERAL, false), // 21
        LAST_YEAR_TAX_RETURNS("Personal Tax Returns", Category.BORROWER_DOCS, Group.PERSONAL, false), // 13
        LOAN_PURPOSE_SUPPORT("Documents to Support Loan Purpose", Category.BORROWER_DOCS, Group.GENERAL, false), // 20
        MARRIAGE_CERTIFICATE("Marriage Certificate", Category.BORROWER_DOCS, Group.GENERAL, false), // 22
        PROOF_OF_OTHER_LIQUID_ASSETS("Proof of Other Liquid Assets", Category.BORROWER_DOCS, Group.GENERAL, false), // 23
        ACADEMIC_TRANSCRIPT("Applicant's Transcript", Category.BORROWER_DOCS, Group.STUDENT, false), // 17
        SCHOOL_ADMISSION_LETTER("School Admission Letter", Category.BORROWER_DOCS, Group.STUDENT, false), // 24
        SCHOOL_TUITION_BILL("School Tuition Bill", Category.BORROWER_DOCS, Group.STUDENT, false), // 25
        COSIGNER_IDENTITY_CARD("Co-signer's ID Card", Category.BORROWER_DOCS, Group.STUDENT, false), // 26
        COSIGNER_PBOC_CREDIT_REPORT("Co-signer's PBOC Credit Report", Category.BORROWER_DOCS, Group.STUDENT, false), // 27
        COSIGNER_MARRIAGE_CERTIFICATE("Co-signer's Marriage Certificate", Category.BORROWER_DOCS, Group.STUDENT, false), // 28
        COSIGNER_LAST_YEAR_TAX_RETURNS("Co-signer's Personal Tax Returns", Category.BORROWER_DOCS, Group.STUDENT, false), // 29
        EMPLOYMENT_CONTRACT("Employment Contract", Category.BORROWER_DOCS, Group.PERSONAL, false), // 30
        PHONE_RECORD("Mobile Phone Record", Category.BORROWER_DOCS, Group.PERSONAL, false), // 31
        OTHER_DOCUMENTS("Other Documents", Category.BORROWER_DOCS, Group.PERSONAL, false), // 32
        // SL SMB Borrower documents
        COM_BANK_STATEMENT("Company Bank Statement", Category.BORROWER_DOCS, Group.SMB, false), // 33
        COM_REVENUE_PROOF("Company revenue proof", Category.BORROWER_DOCS, Group.SMB, false), // 34
        COM_REVENUE_LICENSE("Company revenue license", Category.BORROWER_DOCS, Group.SMB, false), // 35
        COM_CERT_ORGANIZATION_CODE("Certificate of Organization Code", Category.BORROWER_DOCS, Group.SMB, false), // 36
        COM_TAX_REGISTRATION_CERT("Tax registration certificate", Category.BORROWER_DOCS, Group.SMB, false), // 37
        COM_COMMITMENT_LETTER("Commitment letter", Category.BORROWER_DOCS, Group.SMB, false), // 39
        //
        COM_MARKTING_CONTRACT("Company markting contract", Category.BORROWER_DOCS, Group.SMB, false), // 40
        COM_ELECTRICITY_BILL("Company electricity bill", Category.BORROWER_DOCS, Group.SMB, false), // 41
        COM_ASSET_PROOF_PAPER("Company assets proof", Category.BORROWER_DOCS, Group.SMB, false), // 42
        COM_PBOC_CREDIT_REPORT("Company PBOC Credit Report", Category.BORROWER_DOCS, Group.SMB, false), // 43
        COM_CAPITAL_VERIFICATION_REPORT("Company capital verification report", Category.BORROWER_DOCS, Group.SMB, false), // 44
        COM_ASSOCIATION_ARTICLES("Articles of association", Category.BORROWER_DOCS, Group.SMB, false), // 45

        // For admin use only
        COM_INSITE_REPORT("Site investigation report", Category.BORROWER_DOCS, Group.SMB, true),
        COM_NEGATIVE_INFO_INQUIRIES(
                "Negative information inquiries and other",
                Category.BORROWER_DOCS,
                Group.GENERAL,
                true),
        //OTHER BORROWER VERIFICATION
        REGISTER_EMAIL("REGISTER EMAIL", Category.GENERAL, false),
        MOBILE("Mobile", Category.GENERAL, false),
        COMPANY_PHONE("Company phone", Category.GENERAL, false);

        private Category category = null;

        private Group group = null;

        private String label = null;

        private boolean internalUseOnly = false;

        private Type(String pLabel, Category pCategory, boolean pInternalUseOnly) {
            category = pCategory;
            label = pLabel;
            internalUseOnly = pInternalUseOnly;
        }

        private Type(String pLabel, Category pCategory, Group group, boolean pInternalUseOnly) {
            category = pCategory;
            this.group = group;
            label = pLabel;
            internalUseOnly = pInternalUseOnly;
        }

        public Category getCategory() {
            return category;
        }

        public Group getGroup() {
            return this.group;
        }

        public String getLabel() {
            return label;
        }

        public boolean isForInternalUseOnly() {
            return internalUseOnly;
        }

        public static List<Type> getDocumentTypesByCategory(Category cat) {
            // If the category is any we just return them all
            if (Category.ANY.equals(cat))
                return Arrays.asList(Type.values());
            // If not we look for the values with that particular category
            List<Type> result = new ArrayList<Type>();
            for (Type type : Type.values())
                if (type.getCategory().equals(cat))
                    result.add(type);
            return result;
        }

        public static List<Type> getDocumentTypesByCategoryGroup(Category cat, Group group) {
            List<Type> result = new ArrayList<Type>();
            for (Type type : Type.values())
                if (type.getCategory().equals(cat) && type.getGroup() == group)
                    result.add(type);
            return result;
        }

    }

    public static enum Status {
        NONE("Not requested"), // Document is not applicable
        REQUESTED("Requested"), // Document has been requested to user
        VERIFIED("Verified"), // Document has been verified
        INCOMPLETE("Incomplete"), // Document has been marked as incomplete, a
                                  // re-submission is required
        REJECTED("Rejected"), // Document has been rejected
        UPLOADED("Uploaded") // Document has been uploaded
        ;

        private String label;

        private Status(String l) {
            this.label = l;
        }

        public String getLabel() {
            return this.label;
        }
    }

    public static enum Category {
        ANY, // 0 - internal use only
        AGREEMENT, // 1 -
        STATEMENT, // 2 -
        TAX, // 3 -
        BORROWER_DOCS, // 4
        STATE_NOTICES, // 5
        GENERAL,
        ;
    }

    public static enum Group {
        GENERAL("通用文档"), //
        SMB("商业贷款文档"), //
        PERSONAL("个人贷款文档"), //
        STUDENT("学生贷款文档"), //
        ;
        private String _label;

        Group(String label) {
            this._label = label;
        }

        public String getLabel() {
            return this._label;
        }
    }

}